import React, {useCallback, useMemo, useState} from 'react'
import {AuthActionsType, bindAuthActions} from '../../../store/action/auth'
import {bindErrorActions, ErrorActionsType} from '../../../store/action/error'
import {apiPost} from '../../../api'
import {CONSTANTS} from '../../../../constants'
import {LSKeys, LSMethods} from '../../../storage'
import {connectComponent} from '../../../store/utils'
import {SingUpComponent} from './SingUpComponent'
import {UserDto} from '../../../../api/UserDto'
import {UserPasswordDto} from '../../../../api/UserPasswordDto'
import {IResponse} from '../../../api/IResponse'

interface SingUpContainerProps {
  user: UserDto
  authActions: AuthActionsType
  errorActions: ErrorActionsType
}

const SingUpContainer: React.FC<SingUpContainerProps> = ({
  user,
  authActions,
  errorActions,
}): React.ReactElement => {
  const [isSendingRequest, setIsSendingRequest] = useState<boolean>(false)
  const [userPassword, setUserPassword] = useState<UserPasswordDto>({
    login: '',
    password: '',
    repeatPassword: '',
  })
  const [errorMessage, setErrorMessage] = useState<string>(null)

  const handleChangeUserPasswordProps = useCallback(
    (key: string, value: string) => {
      userPassword[key] = value
      setUserPassword({...userPassword})
      setErrorMessage(null)
    },
    [userPassword],
  )

  const isSubmitDisabled = useCallback(() => {
    return (
      isSendingRequest ||
      !userPassword.password ||
      !userPassword.repeatPassword ||
      !userPassword.login ||
      userPassword.password !== userPassword.repeatPassword
    )
  }, [isSendingRequest, userPassword.login, userPassword.password, userPassword.repeatPassword])

  const onLogin = useCallback(async (): Promise<void> => {
    setIsSendingRequest(true)
    try {
      const res = await apiPost(CONSTANTS.apiUrl + '/register', userPassword, {}) //TODO:: any
      if (res?.result) {
        LSMethods.setStorageData(LSKeys.TOKEN, res.result)
        const resCheck: IResponse = await apiPost(
          CONSTANTS.apiUrl + '/auth/check',
          {
            token: res.result as string,
          },
          {},
        )
        const userDB: UserDto = resCheck.result
        authActions.setState({userDB})
        window.location.replace(CONSTANTS.webUrl + '/')
      }
      setIsSendingRequest(false)
    } catch (e: any) {
      setIsSendingRequest(false)
      setErrorMessage(e.errorMessage)
      throw e
    }
  }, [authActions, userPassword])

  return useMemo(() => {
    return (
      <SingUpComponent
        userPassword={userPassword}
        handleChangeUserPasswordProps={handleChangeUserPasswordProps}
        isSubmitDisabled={isSubmitDisabled()}
        onLogin={onLogin}
        errorMessage={errorMessage}
      />
    )
  }, [handleChangeUserPasswordProps, isSubmitDisabled, onLogin, userPassword, errorMessage])
}

export default connectComponent(
  (state) => ({
    user: state.auth.user,
  }),
  (dispatch) => ({
    errorActions: bindErrorActions(dispatch),
    authActions: bindAuthActions(dispatch),
  }),
  SingUpContainer,
)
